/*
 * Copyright 2019 Flipkart Internet Pvt. Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.flipkart.ohos.proteus.api;

import com.flipkart.ohos.proteus.Proteus;
import com.flipkart.ohos.proteus.ProteusBuilder;
import com.flipkart.ohos.proteus.Styles;
import com.flipkart.ohos.proteus.gson.ProteusTypeAdapterFactory;
import com.flipkart.ohos.proteus.recyclerview.v7.ListContainerModule;
import com.flipkart.ohos.proteus.support.v4.SupportV4Module;
import com.flipkart.ohos.proteus.support.v7.CardViewModule;
import com.flipkart.ohos.proteus.utils.HiExecutor;
import com.flipkart.ohos.proteus.value.Layout;
import com.flipkart.ohos.proteus.value.ObjectValue;

import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import retrofit2.Retrofit;

public class ProteusManager {
    private final ProteusApi api;
    private final Proteus proteus;

    private ObjectValue data;
    private Layout rootLayout;
    private Map<String, Layout> layouts;
    private Styles styles;
    private ProteusManager proteusManager;
    private final Set<Listener> listeners = new HashSet<>();

    public ProteusManager(Retrofit retrofit) {
        this.api = retrofit.create(ProteusApi.class);

        proteus = new ProteusBuilder()
            .register(SupportV4Module.create())
            .register(ListContainerModule.create())
            .register(CardViewModule.create())
            .build();

        ProteusTypeAdapterFactory.PROTEUS_INSTANCE_HOLDER.setProteus(proteus);
    }

    public void load() {
        dataLoaderTask(this);
    }

    public void update() {
        dataLoaderTask(this);
    }

    public Proteus getProteus() {
        return proteus;
    }

    public ObjectValue getData() {
        return data;
    }

    public Layout getRootLayout() {
        return rootLayout;
    }

    public Map<String, Layout> getLayouts() {
        return layouts;
    }

    public Styles getStyles() {
        return styles;
    }

    public void addListener(Listener listener) {
        listeners.add(listener);
    }

    public void removeListener(Listener listener) {
        listeners.remove(listener);
    }

    private void broadcast(String e) {
        if ("加载成功".equals(e)) {
            notifySuccess();
        } else {
            notifyError(e);
        }
    }

    private void notifySuccess() {
        for (Listener listener : listeners) {
            listener.onLoad();
        }
    }

    private void notifyError(String e) {
        for (Listener listener : listeners) {
            listener.onError(e);
        }
    }

    private void dataLoaderTask(ProteusManager manager) {
        this.proteusManager = manager;
        HiExecutor.runBg(() -> {
            try {
                proteusManager.rootLayout = api.getLayout().execute().body();
                proteusManager.layouts = api.getLayouts().execute().body();
                proteusManager.data = api.getUserData().execute().body();
                proteusManager.styles = api.getStyles().execute().body();
                if (rootLayout.type != null) {
                    HiExecutor.runUi(() -> broadcast("加载成功"));
                }
            } catch (IOException e) {
                HiExecutor.runUi(() -> broadcast(e.getMessage()));
            }
        });
    }

    public interface Listener {
        void onLoad();

        void onError(String e);
    }
}
